<template>
  <div class="" :style="{height: $store.state.height + 'px'}" style="width: 100%;position: relative;">
    <div id="measurement-map" :style="{height: $store.state.height + 'px', width: '100%'}"></div>
    <el-select v-model="type" placeholder="请选择" class="darw-type" @change="typeChange" style="width: 120px;">
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value">
      </el-option>
    </el-select>
    <div class="draw-tools">
      <a @click="clearSource()">Clear</a>
    </div>
  </div>
</template>

<script>
import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
import { OSM, Vector as VectorSource } from 'ol/source'
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style'

import { unByKey } from 'ol/Observable'
import Overlay from 'ol/Overlay'
import { getArea, getLength } from 'ol/sphere'
import { LineString, Polygon } from 'ol/geom'
import Draw from 'ol/interaction/Draw'

const raster = new TileLayer({
  source: new OSM()
})

const source = new VectorSource()

const vector = new VectorLayer({
  source: source,
  style: new Style({
    fill: new Fill({
      color: 'rgba(255, 255, 255, 0.2)'
    }),
    stroke: new Stroke({
      color: '#ffcc33',
      width: 2
    }),
    image: new CircleStyle({
      radius: 7,
      fill: new Fill({
        color: '#ffcc33'
      })
    })
  })
})

var helpTooltip
var helpTooltipElement
var measureTooltip
var measureTooltipElement

export default {
  name: "measurement",
  title: "地图测量",
  data () {
    return {
      type: '',
      options: [
        {label: '测量距离', value: 'LineString'},
        {label: '测量面积', value: 'Polygon'},
        {label: '不测量', value: ''}
      ],
      map: {},
      draw: null,
      sketch: null,
      continuePolygonMsg: '点击继续绘制多边形',
      continueLineMsg: '点击继续绘制折线'
    }
  },
  mounted () {
    this.map = new Map({
      target: 'measurement-map',
      layers: [raster, vector],
      view: new View({
        center: [11000000, 4600000],
        zoom: 4
      })
    })
    // if (this.type) {
    //   this.map.on('pointermove', this.pointerMoveHandler)
    //   this.addInteraction()
    //   this.map.getViewport().addEventListener('mouseout', () =>{
    //     helpTooltipElement.classList.add('hidden')
    //   })
    // }
  },
  methods: {
    pointerMoveHandler (evt) {
      if (evt.dragging) {
        return
      }
      let helpMsg = '点击开始测量'
      if (this.sketch) {
        let geom = this.sketch.getGeometry()
        if (geom instanceof Polygon) {
          helpMsg = this.continuePolygonMsg
        } else if (geom instanceof LineString) {
          helpMsg = this.continueLineMsg
        }
      }
      helpTooltipElement.innerHTML = helpMsg
      helpTooltip.setPosition(evt.coordinate)
      helpTooltipElement.classList.remove('hidden')
    },
    createHelpTooltip () {
      if (helpTooltipElement) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement)
      }
      helpTooltipElement = document.createElement('div')
      helpTooltipElement.className = 'tooltip hidden'
      helpTooltip = new Overlay({
        element: helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left'
      })
      this.map.addOverlay(helpTooltip)
    },
    createMeasureTooltip () {
      if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement)
      }
      measureTooltipElement = document.createElement('div')
      measureTooltipElement.className = 'tooltip tooltip-measure'
      measureTooltip = new Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
      })
      this.map.addOverlay(measureTooltip)
    },
    formatLength (line) {
      let length = getLength(line)
      let output
      if (length > 100) {
        output = (Math.round(length / 1000 * 100) / 100) + ' ' + 'km'
      } else {
        output = (Math.round(length * 100) / 100) + ' ' + 'm'
      }
      return output
    },
    formatArea (polygon) {
      let area = getArea(polygon)
      let output
      if (area > 10000) {
        output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>'
      } else {
        output = (Math.round(area / 100 * 100) / 100) + ' ' + 'm<sup>2</sup>'
      }
      return output
    },
    addInteraction () {
      this.draw = new Draw({
        source: source,
        type: this.type,
        style: new Style({
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          }),
          stroke: new Stroke({
            color: 'rgba(0, 0, 0, 0.5)',
            lineDash: [10, 10],
            width: 2
          }),
          image: new CircleStyle({
            radius: 5,
            stroke: new Stroke({
              color: 'rgba(0, 0, 0, 0.7)'
            }),
            fill: new Fill({
              color: 'rgba(255, 255, 255, 0.4)'
            })
          })
        })
      })
      this.map.addInteraction(this.draw)
      this.createHelpTooltip()
      this.createMeasureTooltip()

      let listener

      this.draw.on('drawstart', (evt) => {
        // set sketch
        this.sketch = evt.feature
        let tooltipCoord = evt.coordinate
        listener = this.sketch.getGeometry().on('change', (evt) => {
          let geom = evt.target
          let output
          if (geom instanceof Polygon) {
            output = this.formatArea(geom)
            tooltipCoord = geom.getInteriorPoint().getCoordinates()
          } else if (geom instanceof LineString) {
            output = this.formatLength(geom)
            tooltipCoord = geom.getLastCoordinate()
          }
          measureTooltipElement.innerHTML = output
          measureTooltip.setPosition(tooltipCoord)
        })
      }, this)

      this.draw.on('drawend', () => {
        measureTooltipElement.className = 'tooltip tooltip-static'
        measureTooltip.setOffset([0, -7])
        // unset sketch
        this.sketch = null
        // unset tooltip so that a new one can be created
        measureTooltipElement = null
        this.createMeasureTooltip()
        unByKey(listener)
      }, this)

    },
    typeChange (value) {
      this.map.removeInteraction(this.draw)
      this.map.un('pointermove', () => {
        console.log('移除鼠标移动事件')
      })
      this.map.getViewport().removeEventListener('mouseout', () => {
        console.log('移除监听')
      })
      if (value) {
        this.addInteraction()
        this.map.on('pointermove', this.pointerMoveHandler)
        this.map.getViewport().addEventListener('mouseout', () =>{
          helpTooltipElement.classList.add('hidden')
        })
      }
    },
    clearSource () {
      source.clear()
      this.map.getOverlays().clear()
    }
  }
}
</script>

<style lang="scss">
.darw-type {
  position: absolute;
  top: 1rem;
  right: 1rem;
}
.modify-type {
  position: absolute;
  top: 4rem;
  right: 1rem;
}
.draw-tools {
  position: absolute;
  top: 4rem;
  right: 1rem;
  a {
    display: inline-block;
    padding: 0.5rem;
    background: white;
    cursor: pointer;
  }
}
.tooltip {
  position: relative;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  color: white;
  padding: 4px 8px;
  opacity: 0.7;
  white-space: nowrap;
}
.tooltip-measure {
  opacity: 1;
  font-weight: bold;
}
.tooltip-static {
  background-color: #ffcc33;
  color: black;
  border: 1px solid white;
}
.tooltip-measure:before,
.tooltip-static:before {
  border-top: 6px solid rgba(0, 0, 0, 0.5);
  border-right: 6px solid transparent;
  border-left: 6px solid transparent;
  content: "";
  position: absolute;
  bottom: -6px;
  margin-left: -7px;
  left: 50%;
}
.tooltip-static:before {
  border-top-color: #ffcc33;
}
</style>
